package com.jackeysun.log

import android.os.Build
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import java.io.*
import java.lang.StringBuilder
import java.util.*
import androidx.recyclerview.widget.LinearLayoutManager

import androidx.recyclerview.widget.RecyclerView




/**
 *   Created by sunxunchao on 2021/12/10.
 */

private val mMutex = Mutex()

suspend fun String.toFile(file: File) {
    withContext(Dispatchers.IO) {
        val success = if (!file.exists()) {
            try {
                file.createNewFile()
            } catch (e: Exception) {
                false
            }
        } else {
            true
        }
        if (success) {
            mMutex.withLock {
                var fw: FileWriter? = null
                try {
                    fw = FileWriter(file, file.length() < LogConfig.fileSize)
                    fw.write(String.format("%s", this@toFile))
                } catch (e: Exception) {
                    e.printStackTrace()
                } finally {
                    fw?.flush()
                    fw?.close()
                }
            }
        }
    }
}

fun Throwable?.crashInfo(): String {
    return if (this == null) "" else {
        val writer: Writer = StringWriter()
        val printWriter = PrintWriter(writer)
        this.printStackTrace(printWriter)
        var throwable: Throwable? = this.cause
        while (throwable != null) {
            throwable.printStackTrace(printWriter)
            throwable = throwable.cause //逐级获取错误信息
        }
        val crashInfo = writer.toString()
        printWriter.close()
        crashInfo
    }
}

fun File.read(): String {
    var fr: FileReader? = null
    try {
        if (!this.exists()) {
            return ""
        }
        val n: Long = LogConfig.fileSize
        val len = this.length()
        val skip = len - n
        fr = FileReader(this)
        fr.skip(Math.max(0, skip))
        val cs = CharArray(Math.min(len, n).toInt())
        fr.read(cs)
        return String(cs).trim { it <= ' ' }
    } catch (ex: Throwable) {
        ex.printStackTrace()
    } finally {
        try {
            fr?.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
    return ""
}

fun File.readOnLine(): List<String>? {
    var fr: FileReader? = null
    try {
        if (!this.exists()) {
            return null
        }
        fr = FileReader(this)
        return fr.readLines()
    } catch (ex: Throwable) {
        ex.printStackTrace()
    } finally {
        try {
            fr?.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
    return null
}

fun File.forEachLine(block: (log: String) -> Unit) {
    var fr: FileReader? = null
    try {
        if (!this.exists()) {
            return
        }
        fr = FileReader(this)
        return fr.forEachLine(block)
    } catch (ex: Throwable) {
        ex.printStackTrace()
    } finally {
        try {
            fr?.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
}

fun deviceInfo(): String {
    val sb = StringBuilder()
    //App版本
    sb.append("App Version: ")
    sb.append(LogConfig.versionName)
    sb.append("_")
    sb.append("${LogConfig.versionCode}\n")
    //Android版本号
    sb.append("OS Version: ")
    sb.append(Build.VERSION.RELEASE)
    sb.append("_")
    sb.append("${Build.VERSION.SDK_INT}\n")
    //手机制造商
    sb.append("Vendor: ")
    sb.append("${Build.MANUFACTURER}\n")
    //手机型号
    sb.append("Model: ")
    sb.append("${Build.MODEL}\n")
    //CPU架构
    sb.append("CPU: ")
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        sb.append(Arrays.toString(Build.SUPPORTED_ABIS))
    } else {
        sb.append(Build.CPU_ABI)
    }
    return sb.toString()
}


fun deleteOverdueFile(file: File) {
    val files: Array<File> = file.getLogFileList() ?: return
    val current = System.currentTimeMillis()
    for (file in files) {
        if (file.exists()) {
            val time = file.lastModified()
            if (current - time > LogConfig.saveFileTime) {
                file.delete()
            }
        }
    }
}

fun File.getLogFileList(): Array<File>? {
    val file = File(this.absolutePath)
    return if (file.exists() && !file.isFile) {
        file.listFiles()
    } else null
}

